package com.sdy.hospitalguard.embed.task;

import com.sdy.common.utils.StringUtil;
import com.sdy.hospitalguard.biz.constants.MqConstants;
import com.sdy.mq.service.MqProducerService;
import com.sdy.mvc.utils.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 监听终端
 * </p>
 *
 * @author fb
 * @since 2020/5/6
 */
@Slf4j
public class Server{
//public class Server implements CommandLineRunner {

    @Value("${netty.http.port}")
    private Integer port;

    @Autowired
    private MqProducerService mqProducerService;

/*    @Override
    public void run(String... args) throws Exception {
        log.info("------------------开始监听------------------");
        init();
    }*/

    public void init() {
        try {
            //创建一个ServerSocket，这里可以指定连接请求的队列长度
            //new ServerSocket(port,3);意味着当队列中有3个连接请求是，如果Client再请求连接，就会被Server拒绝
            ServerSocket serverSocket = new ServerSocket(port);
            while (true) {
                //从请求队列中取出一个连接
                Socket client = serverSocket.accept();
                // 处理这次连接
                new Thread(new HandlerThread(client)).start();
            }
        } catch (Exception e) {
            log.error("服务器异常: ", e);
        }
    }

    private class HandlerThread implements Runnable {
        private Socket socket;
        public HandlerThread(Socket client) {
            socket = client;
        }
        @Override
        public void run() {
            try {
                // 读取客户端数据
                try (BufferedInputStream input = new BufferedInputStream(socket.getInputStream())) {
                    while (true) {
                        String request = readPostReq(input);
                        try {
                            mqProducerService.send(MqConstants.Tags.TAG_EMBED_SERVER, request, true);
                        }catch (Exception e) {
                            log.error("消息发送异常: ", e);
                        }
                    }
                }
            } catch (Exception e) {
                log.error("服务器 run 异常: ", e);
            } finally {

            }
        }
    }

    private String readLine(BufferedInputStream input) throws IOException {
        byte[] s = new byte[1024];
        int size = 0;
        do {
            input.read(s, size, 1);
        } while (s[size++] != 0x0A);
        String ss = new String(s, 0, size).trim();
        return ss;
    }

    private String readPostReq(BufferedInputStream input) throws IOException {
        String urls = readLine(input).trim();
        String method = urls.split("\\s+")[0];
        String url = urls.split("\\s+")[1];
        String httpVersion = urls.split("\\s+")[2];
        Map<String, String> headerMap = readPostHeader(input);
        String jsonStr = readBody(input, Integer.parseInt(headerMap.getOrDefault("content-length", "0")));
        String request = url + "##hzsdy##" + jsonStr;
        return request;
    }

    private Map<String, String> readPostHeader(BufferedInputStream input) throws IOException {
        Map<String, String> headerMap = new HashMap<>();
        String line;
        while (StringUtil.isNotBlank(line = readLine(input).trim())) {
            String[] array = line.split(":");
            String key = array[0].toLowerCase().trim();
            String value = array[1].trim();
            headerMap.put(key, value);
        }
        return headerMap;
    }

    private String readBody(BufferedInputStream input, int length) throws IOException {
        if (length == 0) {
            return "";
        }
        byte[] buf = new byte[length];
        int len = 0;
        do {
            len += input.read(buf, len, length - len);
        } while (len < length);
        return new String(buf);
    }

}
